home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / wgdb-42.lha / wgdb-4.2 / gdb / i386-xdep.c < prev    next >
C/C++ Source or Header  |  1992-09-11  |  6KB  |  242 lines

  1. /* Intel 386 stuff.
  2.    Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
  3.  
  4. This file is part of GDB.
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include <stdio.h>
  21. #include "defs.h"
  22. #include "param.h"
  23. #include "frame.h"
  24. #include "inferior.h"
  25. #include "language.h"
  26. #include "gdbcore.h"
  27.  
  28. #ifdef USG
  29. #include <sys/types.h>
  30. #endif
  31.  
  32. #include <sys/param.h>
  33. #include <sys/dir.h>
  34. #include <signal.h>
  35. #include <sys/user.h>
  36. #include <sys/ioctl.h>
  37. #include <fcntl.h>
  38.  
  39. #include <sys/file.h>
  40. #include <sys/stat.h>
  41.  
  42. #include <sys/reg.h>
  43. #include "ieee-float.h"
  44.  
  45. extern void print_387_control_word ();        /* i387-tdep.h */
  46. extern void print_387_status_word ();
  47.  
  48. extern struct ext_format ext_format_i387;
  49.  
  50. /* this table must line up with REGISTER_NAMES in m-i386.h */
  51. /* symbols like 'EAX' come from <sys/reg.h> */
  52. static int regmap[] = 
  53. {
  54.   EAX, ECX, EDX, EBX,
  55.   UESP, EBP, ESI, EDI,
  56.   EIP, EFL, CS, SS,
  57.   DS, ES, FS, GS,
  58. };
  59.  
  60. /* blockend is the value of u.u_ar0, and points to the
  61.  * place where GS is stored
  62.  */
  63. i386_register_u_addr (blockend, regnum)
  64. {
  65. #if 0
  66.   /* this will be needed if fp registers are reinstated */
  67.   /* for now, you can look at them with 'info float'
  68.    * sys5 wont let you change them with ptrace anyway
  69.    */
  70.   if (regnum >= FP0_REGNUM && regnum <= FP7_REGNUM) 
  71.     {
  72.       int ubase, fpstate;
  73.       struct user u;
  74.       ubase = blockend + 4 * (SS + 1) - KSTKSZ;
  75.       fpstate = ubase + ((char *)&u.u_fpstate - (char *)&u);
  76.       return (fpstate + 0x1c + 10 * (regnum - FP0_REGNUM));
  77.     } 
  78.   else
  79. #endif
  80.     return (blockend + 4 * regmap[regnum]);
  81.   
  82. }
  83.  
  84. struct env387 
  85. {
  86.   unsigned short control;
  87.   unsigned short r0;
  88.   unsigned short status;
  89.   unsigned short r1;
  90.   unsigned short tag;
  91.   unsigned short r2;
  92.   unsigned long eip;
  93.   unsigned short code_seg;
  94.   unsigned short opcode;
  95.   unsigned long operand;
  96.   unsigned short operand_seg;
  97.   unsigned short r3;
  98.   unsigned char regs[8][10];
  99. };
  100.  
  101. static
  102. print_387_status (status, ep)
  103.      unsigned short status;
  104.      struct env387 *ep;
  105. {
  106.   int i;
  107.   int bothstatus;
  108.   int top;
  109.   int fpreg;
  110.   unsigned char *p;
  111.   
  112.   bothstatus = ((status != 0) && (ep->status != 0));
  113.   if (status != 0) 
  114.     {
  115.       if (bothstatus)
  116.     printf ("u: ");
  117.       print_387_status_word (status);
  118.     }
  119.   
  120.   if (ep->status != 0) 
  121.     {
  122.       if (bothstatus)
  123.     printf ("e: ");
  124.       print_387_status_word (ep->status);
  125.     }
  126.   
  127.   print_387_control_word (ep->control);
  128.   printf ("last exception: ");
  129.   printf ("opcode %s; ", local_hex_string(ep->opcode));
  130.   printf ("pc %s:", local_hex_string(ep->code_seg));
  131.   printf ("%s; ", local_hex_string(ep->eip));
  132.   printf ("operand %s", local_hex_string(ep->operand_seg));
  133.   printf (":%s\n", local_hex_string(ep->operand));
  134.   
  135.   top = (ep->status >> 11) & 7;
  136.   
  137.   printf ("regno  tag  msb              lsb  value\n");
  138.   for (fpreg = 7; fpreg >= 0; fpreg--) 
  139.     {
  140.       double val;
  141.       
  142.       printf ("%s %d: ", fpreg == top ? "=>" : "  ", fpreg);
  143.       
  144.       switch ((ep->tag >> (fpreg * 2)) & 3) 
  145.     {
  146.     case 0: printf ("valid "); break;
  147.     case 1: printf ("zero  "); break;
  148.     case 2: printf ("trap  "); break;
  149.     case 3: printf ("empty "); break;
  150.     }
  151.       for (i = 9; i >= 0; i--)
  152.     printf ("%02x", ep->regs[fpreg][i]);
  153.       
  154.       ieee_extended_to_double (&ext_format_i387, (char *)ep->regs[fpreg],
  155.                    &val);
  156.       printf ("  %g\n", val);
  157.     }
  158.   if (ep->r0)
  159.     printf ("warning: reserved0 is %s\n", local_hex_string(ep->r0));
  160.   if (ep->r1)
  161.     printf ("warning: reserved1 is %s\n", local_hex_string(ep->r1));
  162.   if (ep->r2)
  163.     printf ("warning: reserved2 is %s\n", local_hex_string(ep->r2));
  164.   if (ep->r3)
  165.     printf ("warning: reserved3 is %s\n", local_hex_string(ep->r3));
  166. }
  167.  
  168. #ifndef U_FPSTATE
  169. #define U_FPSTATE(u) u.u_fpstate
  170. #endif
  171.  
  172. i386_float_info ()
  173. {
  174.   struct user u; /* just for address computations */
  175.   int i;
  176.   /* fpstate defined in <sys/user.h> */
  177.   struct fpstate *fpstatep;
  178.   char buf[sizeof (struct fpstate) + 2 * sizeof (int)];
  179.   unsigned int uaddr;
  180.   char fpvalid;
  181.   unsigned int rounded_addr;
  182.   unsigned int rounded_size;
  183.   extern int corechan;
  184.   int skip;
  185.   
  186.   uaddr = (char *)&u.u_fpvalid - (char *)&u;
  187.   if (have_inferior_p()) 
  188.     {
  189.       unsigned int data;
  190.       unsigned int mask;
  191.       
  192.       rounded_addr = uaddr & -sizeof (int);
  193.       data = ptrace (3, inferior_pid, rounded_addr, 0);
  194.       mask = 0xff << ((uaddr - rounded_addr) * 8);
  195.       
  196.       fpvalid = ((data & mask) != 0);
  197.     } 
  198.   else 
  199.     {
  200.       if (lseek (corechan, uaddr, 0) < 0)
  201.     perror ("seek on core file");
  202.       if (myread (corechan, &fpvalid, 1) < 0) 
  203.     perror ("read on core file");
  204.       
  205.     }
  206.   
  207.   if (fpvalid == 0) 
  208.     {
  209.       printf ("no floating point status saved\n");
  210.       return;
  211.     }
  212.   
  213.   uaddr = (char *)&U_FPSTATE(u) - (char *)&u;
  214.   if (have_inferior_p ()) 
  215.     {
  216.       int *ip;
  217.       
  218.       rounded_addr = uaddr & -sizeof (int);
  219.       rounded_size = (((uaddr + sizeof (struct fpstate)) - uaddr) +
  220.               sizeof (int) - 1) / sizeof (int);
  221.       skip = uaddr - rounded_addr;
  222.       
  223.       ip = (int *)buf;
  224.       for (i = 0; i < rounded_size; i++) 
  225.     {
  226.       *ip++ = ptrace (3, inferior_pid, rounded_addr, 0);
  227.       rounded_addr += sizeof (int);
  228.     }
  229.     } 
  230.   else 
  231.     {
  232.       if (lseek (corechan, uaddr, 0) < 0)
  233.     perror_with_name ("seek on core file");
  234.       if (myread (corechan, buf, sizeof (struct fpstate)) < 0) 
  235.     perror_with_name ("read from core file");
  236.       skip = 0;
  237.     }
  238.   
  239.   fpstatep = (struct fpstate *)(buf + skip);
  240.   print_387_status (fpstatep->status, (struct env387 *)fpstatep->state);
  241. }
  242.